from django.utils.translation import gettext_lazy, gettext as _
from django.utils.functional import lazy
from rest_framework.permissions import IsAuthenticated
from rest_framework.serializers import Serializer, DateTimeField as DRFDateTimeField
from rest_framework.decorators import action
from rest_framework.response import Response
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

from core import errors
from apps.api.paginations import NewPageNumberPagination100
from apps.api.viewsets import NormalGenericViewSet
from apps.app_service.odc_manager import OrgDataCenterManager
from apps.app_ai.serializers import AIHubServiceSerializer, AIHubServiceAdminSerializer
from apps.app_ai.models import AIHubService
from apps.app_ai.managers.aihub import AIHubServiceManager


class AIHubServiceViewSet(NormalGenericViewSet):
    permission_classes = [IsAuthenticated]
    pagination_class = NewPageNumberPagination100
    lookup_field = 'id'

    @swagger_auto_schema(
        tags=['ai'],
        operation_summary=gettext_lazy('列举AIHub服务单元'),
        manual_parameters=[
            openapi.Parameter(
                name='status',
                in_=openapi.IN_QUERY,
                type=openapi.TYPE_STRING,
                required=False,
                description=lazy(str, str)(AIHubService.Status.choices)
            ),
            openapi.Parameter(
                name='id',
                in_=openapi.IN_QUERY,
                type=openapi.TYPE_STRING,
                required=False,
                description=gettext_lazy('id查询')
            ),
        ],
        responses={
            200: ''''''
        }
    )
    def list(self, request, *args, **kwargs):
        """
        列举AIHub服务单元

            http code 200:
            {
              "count": 1,
              "page_num": 1,
              "page_size": 100,
              "results": [
                {
                  "id": "gikeog6vr0pd402o89udgpx16",
                  "name": "AIHub服务test",
                  "name_en": "AIHub service test",
                  "endpoint_url": "https://xxx.com/",
                  "creation": "2025-02-28T05:55:03.830116Z",
                  "modification": "2025-02-28T05:57:12.663156Z",
                  "status": "enable",   # enable: 开启状态；disable: 停止服务状态; deleted: 删除
                  "longitude": 0,
                  "latitude": 0,
                  "sort_weight": 0,
                  "version": "v1.x.x",  # maybe null
                  "version_update_time": "2025-02-28T05:57:12.663156Z",
                  "org_data_center": {  # maybe null
                    "id": "gii8wpgvtna8xvujhkf3496qo",
                    "name": "AIOps云节点",
                    "name_en": "AIOps data center",
                    "sort_weight": -1008,
                    "organization": {   # maybe null
                      "id": "1",
                      "name": "中国科学院计算机网络信息中心",
                      "name_en": "Computer Network Information Center,  Chinese Academy of Sciences",
                      "sort_weight": -9
                    }
                  }
                }
              ]
            }
        """
        status = request.query_params.get('status', None)
        service_id = request.query_params.get('id', None)

        try:
            if status and status not in AIHubService.Status.values:
                raise errors.InvalidArgument(message=_('无效的状态类型'))

            queryset = AIHubService.objects.all()
            if status:
                queryset = queryset.filter(status=status)

            if service_id:
                queryset = queryset.filter(id=service_id)

            objs = self.paginate_queryset(queryset)
            serializer = self.get_serializer(objs, many=True)
            return self.get_paginated_response(serializer.data)
        except Exception as exc:
            return self.exception_response(exc=exc)

    @swagger_auto_schema(
        tags=['ai'],
        operation_summary=gettext_lazy('列举有管理员权限的AIHub服务单元'),
        manual_parameters=[
            openapi.Parameter(
                name='status',
                in_=openapi.IN_QUERY,
                type=openapi.TYPE_STRING,
                required=False,
                description=lazy(str, str)(AIHubService.Status.choices)
            ),
            openapi.Parameter(
                name='id',
                in_=openapi.IN_QUERY,
                type=openapi.TYPE_STRING,
                required=False,
                description=gettext_lazy('id查询')
            ),
            openapi.Parameter(
                name='with_admin_users',
                type=openapi.TYPE_STRING,
                in_=openapi.IN_QUERY,
                required=False,
                description=gettext_lazy('要求返回数据包含管理员信息，此参数不需要值')
            ),
        ],
        responses={
            200: ''''''
        }
    )
    @action(methods=['get'], detail=False, url_path='admin', url_name='admin-list')
    def list_admin_services(self, request, *args, **kwargs):
        """
        列举有管理员权限的AIHub服务单元

            http code 200:
            {
              "count": 1,
              "page_num": 1,
              "page_size": 100,
              "results": [
                {
                  "id": "gikeog6vr0pd402o89udgpx16",
                  "name": "AIHub服务test",
                  "name_en": "AIHub service test",
                  "endpoint_url": "https://xxx.com/",
                  "creation": "2025-02-28T05:55:03.830116Z",
                  "modification": "2025-02-28T05:57:12.663156Z",
                  "status": "enable",   # enable: 开启状态；disable: 停止服务状态; deleted: 删除
                  "longitude": 0,
                  "latitude": 0,
                  "sort_weight": 0,
                  "version": "v1.x.x",  # maybe null
                  "version_update_time": "2025-02-28T05:57:12.663156Z",
                  "org_data_center": {  # maybe null
                    "id": "gii8wpgvtna8xvujhkf3496qo",
                    "name": "AIOps云节点",
                    "name_en": "AIOps data center",
                    "sort_weight": -1008,
                    "organization": {   # maybe null
                      "id": "1",
                      "name": "中国科学院计算机网络信息中心",
                      "name_en": "Computer Network Information Center,  Chinese Academy of Sciences",
                      "sort_weight": -9
                    }
                  },
                  "admin_users":[   # 使用参数 with_admin_users 时包含此数据
                    {"id": "xxx", "username": "xxxx", "role": "admin"}  # role: admin(管理员)，ops(运维管理员)
                  ]
                }
              ]
            }
        """
        status = request.query_params.get('status', None)
        service_id = request.query_params.get('id', None)
        with_admin_users = request.query_params.get('with_admin_users', None)

        try:
            if status and status not in AIHubService.Status.values:
                raise errors.InvalidArgument(message=_('无效的状态类型'))

            user_id = request.user.id
            queryset = AIHubService.objects.select_related(
                'org_data_center__organization'
            ).filter(
                org_data_center__users__id=user_id
            ).distinct()

            if status:
                queryset = queryset.filter(status=status)

            if service_id:
                queryset = queryset.filter(id=service_id)

            objs = self.paginate_queryset(queryset)
            if with_admin_users is not None:
                self.services_mixin_admins(services=objs)
                serializer = AIHubServiceAdminSerializer(objs, many=True)
            else:
                serializer = AIHubServiceSerializer(objs, many=True)

            return self.get_paginated_response(serializer.data)
        except Exception as exc:
            return self.exception_response(exc=exc)

    @swagger_auto_schema(
        tags=['ai'],
        operation_summary=gettext_lazy('查询服务单元版本号'),
        responses={
            200: ''
        }
    )
    @action(methods=['get'], detail=True, url_path='version', url_name='version')
    def update_version(self, request, *args, **kwargs):
        """
        查询服务单元版本号

            http code 200:
            {
              "version": "4.2.1",   # 可能为空字符串
              "version_update_time": "2024-05-14T01:46:17.817050Z"  # 可能为空
            }
        """
        try:
            service = AIHubServiceManager.get_service_by_id(_id=kwargs.get(self.lookup_field))
            if service is None:
                raise errors.ServiceNotExist(message=_('服务单元不存在'))

            # if service.status == AIHubService.Status.ENABLE.value:
            ok_or_exc = AIHubServiceManager.update_service_version(service=service)
            if ok_or_exc is not True:
                raise ok_or_exc
        except errors.Error as exc:
            return self.exception_response(exc)

        return Response(data={
            'version': service.version,
            'version_update_time': DRFDateTimeField().to_representation(service.version_update_time)
        }, status=200)

    @staticmethod
    def services_mixin_admins(services: list):
        """
        给服务单元添加管理员列表属性
        """
        service_ids = []
        odc_ids = []
        for sv in services:
            service_ids.append(sv.id)
            if sv.org_data_center_id not in odc_ids:
                odc_ids.append(sv.org_data_center_id)

        odc_admins_map = {}
        if odc_ids:
            odc_admins_map = OrgDataCenterManager.get_odc_admins_map(odc_ids=odc_ids)

        for sv in services:
            admin_dict = {}
            ops_dict = {}
            if sv.org_data_center_id in odc_admins_map:
                odc_admins = odc_admins_map[sv.org_data_center_id]
                for u_id, u in odc_admins.items():
                    if u['role'] == 'admin':
                        admin_dict[u_id] = u
                    else:
                        ops_dict[u_id] = u

            sv.admin_users = list(admin_dict.values()) + list(ops_dict.values())

    def get_serializer_class(self):
        if self.action == 'list':
            return AIHubServiceSerializer

        return Serializer
